package networkSimulation.simulation.animals

import framework._
import networkSimulation.framework.DirectedGraph
import simulation.Animals
import networkSimulation.visualisation.gui.VisualUIFrame
import util.Random
import java.io.IOException

/**
 * Runnable class for an Animal simulation
 *
 * @author  Tim Caljé
 *          Jeroen De Raedt
 *          Jorick Van Aken
 */
object Run {

  /**
   * Create and start the simulation
   *
   * - create a graph
   * - create a simulation with graph
   * - start the simulation
   */
  def main(args: Array[String]) {
    try {
      val graph = createGraph(20,15,5)
      val animals = new Animals(graph)
      var outputPath = "out\\"
      animals.startSimulation(5,outputPath)
      new VisualUIFrame(outputPath)
      new VisualUIFrame(outputPath+"graph")
    } catch {
      case e: IllegalArgumentException => println(e.getMessage)
      case e: IllegalStateException    => println("Illegal state exception: " + e.getMessage)
      case e: IOException              => println("IO exception: " + e.getMessage)
      case e: NullPointerException     => println("NullPointerException: " + e.getMessage)
      case e: Exception                => println("Unknown error: " + e.getMessage)
    }
  }

  /**
   * Create a graph.
   *
   * @param nbAnimals
   *        The number of animals to create
   * @param nbHunts
   *        The number of hunts to create
   * @return A DirectedGraph with nbAnimals Nodes and nbHunts Edges, with types Animal for Node and Hunt for Edge
   */
  private def createGraph(nbRabbits : Int,nbWolfs : Int,nbDinosaurs : Int) : DirectedGraph[Animal,Hunt[Animal]] = {

    val graph = new DirectedGraph[Animal,Hunt[Animal]]
    val nbHunts : Int = nbRabbits + nbDinosaurs 

    var rabbits = List[Rabbit]()
    var dinosaurs = List[Dinosaur]()
    var wolfs = List[Wolf]()

    for (i <- 0 until nbRabbits){
      val n1 = new Rabbit("r"+i)
      graph.addNode(n1)
      rabbits ::= n1
    }
    for (i <- 0 until nbWolfs){
          val n2 = new Wolf("w"+i)
          graph.addNode(n2)
          wolfs ::= n2
    }
    for (i <- 0 until nbDinosaurs){
      val n3 = new Dinosaur("d"+i)
      graph.addNode(n3)
      dinosaurs ::= n3
    }
    
    for (i <- 0 until nbHunts){
      val rnd1 = new Random().nextInt(nbDinosaurs)
      val rnd2 = new Random().nextInt(nbWolfs)
      val rnd3 = new Random().nextInt(nbWolfs)
      val rnd4 = new Random().nextInt(nbRabbits)
      if (new Random().nextInt(3)==2){
         graph.addEdge(new Hunt[Animal](dinosaurs.apply(rnd1),wolfs.apply(rnd2)))
      } else {
         graph.addEdge(new Hunt[Animal](wolfs.apply(rnd3),rabbits.apply(rnd4)))
      }

    }

    graph
  }

}